/*
* Copyright (c) 2025 Huawei Device Co., Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including but not limited to the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to provide persons with access to the Software
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGE OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

<template>
  <div class="list">
    <div
      :class="[
        'music-list',
        deviceType === 'mobile' ? 'mobile-music-list' : 'pc-music-list',
      ]"
      v-interaction="{
        handlers: {
          onScroll: scrollMusicList,
          onSwipe: swipeMusicList,
        },
        configs: {
          enableScroll: true,
          enableSwipe: true,
          speed: 110,
        },
      }"
    >
      <div
        class="music-item"
        v-interaction="{
          handlers: {
            onClick: clickGoPlay,
            onDoubleClick: doubleClickGoPlay,
          },
          configs: {
            enableClick: true,
            enableDoubleClick: true,
          },
        }"
        v-for="item in musicList"
        :data-id="item.id"
        :key="item.id"
      >
        <div class="music-info">
          <div class="music-name">
            <span
              v-interaction="{
                handlers: {
                  onHover: handleHover,
                },
                configs: {
                  enableHover: true,
                },
              }"
              >{{ item.name }}</span
            >
            <img
              v-show="item.isCollect"
              src="../../assets/images/heart_icon.svg"
            />
          </div>
          <div class="music-detail">
            <span>VIP</span>
            <span>空间音频</span>
            <span>{{ item.musicName }}</span>
          </div>
        </div>
        <div class="music-icon">
          <span>
            <img src="../../assets/images/addAndsubtract.svg" />
          </span>
          <span
            v-interaction="{
              handlers: {
                onContextMenu: handleContextMenu,
              },
              configs: {
                enableContextMenu: true,
              },
            }"
          >
            <img draggable="false" src="../../assets/images/detailBtn.svg" />
          </span>
        </div>
      </div>
    </div>
    <div class="shadow-bg" v-show="isShowMenu">
      <div ref="refMenu" class="context-menu">
        <div @click="handleCollect">
          <img src="../../assets/images/heart.svg" />
          <img
            v-show="musicCollect"
            src="../../assets/images/collect_enshrine.svg"
          />
          <img v-show="!musicCollect" src="../../assets/images/add.svg" />
          <span>{{ musicCollect ? "移除收藏" : "收藏到歌单" }}</span>
        </div>
        <div @click="deleteMusic">
          <img src="../../assets/images/delete.svg" />
          <span>删除</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { musicListType } from "../../utils/common";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import { PointerState } from "@hadss/web_uni_input";
import { ref, onMounted, nextTick, watch, defineProps } from "vue";

const router = useRouter();
const store = useStore();
const musicList = ref<musicListType[]>(store.state.musicList);
const musicId = ref<number>(1);
const clickTime = ref<number | null>(null);
const isShowMenu = ref<boolean>(false);
const refMenu = ref<HTMLElement | null>(null);
const musicCollect = ref<boolean | null>(null);
const childElement = ref<any>(undefined);
const isMaxFontSize = ref(false);
const props = defineProps({
  deviceType: {
    type: String,
    default: "mobile",
  },
  listNum: {
    type: Number,
    default: 0,
  },
  updateMusic: {
    type: Object,
    default: undefined,
  },
});
const deviceType = ref<string>(props.deviceType);
const DOUBLE_TAP_THRESHOLD = 300; // 双击超时时间间隔

watch(
  () => props.updateMusic,
  (newVal) => {
    newVal.getOneMusic(musicList.value[newVal.musicId - 1]);
  }
);
watch(
  () => props.deviceType,
  (newVal) => {
    deviceType.value = newVal;
  }
);

const clickGoPlay = (e: PointerState) => {
  childElement.value = e.target;
  musicId.value = childElement.value.closest(".music-item").dataset.id;
  clickTime.value = setTimeout(() => {
    if (!isShowMenu.value) {
      router.push({
        path: "/musicListDetail",
        query: {
          isPlay: 0,
          musicId: musicId.value,
        },
      });
    }
  }, DOUBLE_TAP_THRESHOLD);
};

const handleContextMenu = (e: PointerEvent) => {
  isShowMenu.value = true;
  childElement.value = e.target;
  musicId.value = childElement.value.closest(".music-item").dataset.id;
  const musicItem = musicList.value.find(
    (item) => item.id === Number(musicId.value)
  );
  musicCollect.value = musicItem.isCollect;
  nextTick(() => {
    contextMenuLocation(e);
  });
};

const doubleClickGoPlay = (e: PointerState) => {
  childElement.value = e.target;
  musicId.value = childElement.value.closest(".music-item").dataset.id;
  clearTimeout(clickTime.value);
  router.push({
    path: "/musicListDetail",
    query: {
      isPlay: 1,
      musicId: musicId.value,
    },
  });
};

const scrollMusicList = (e: PointerState) => {
  const childElement = e.target;
  const parentHtml = childElement.closest(".music-list");
  const delta = e.offsetY;
  if (e.source !== "mouse") {
    const scrollStep = Math.abs(delta);
    parentHtml.scrollTo({
      top: parentHtml.scrollTop + (delta >= 0 ? -scrollStep : scrollStep),
    });
  } else {
    const scrollStep = 100;
    parentHtml.scrollTo({
      top: parentHtml.scrollTop + (delta >= 0 ? scrollStep : -scrollStep),
      behavior: "smooth",
    });
  }
};

const swipeMusicList = (e: PointerState) => {
  if (window.innerWidth < 1300) {
    const childElement = e.target;
    const parentHtml = childElement.closest(".music-list");
    const height = parentHtml.getBoundingClientRect().height;
    parentHtml.scrollTo({
      top:
        parentHtml.scrollTop + (e.velocityY >= 0 ? -height + 60 : height - 60),
      behavior: "smooth",
    });
  }
};

const contextMenuLocation = (e: PointerEvent) => {
  const screenHeight = window.innerHeight;
  const menuWidth = refMenu.value.offsetWidth;
  const menuHeight = refMenu.value.offsetHeight;
  let left = e.clientX;
  let top = e.clientY;

  if (top + menuHeight > screenHeight) {
    top = screenHeight - menuHeight;
  }
  refMenu.value.style.left = `${left - menuWidth}px`;
  refMenu.value.style.top = `${top}px`;
};

const handleCollect = () => {
  if (musicId.value) {
    const musicIndex = musicList.value.findIndex(
      (item) => item.id === Number(musicId.value)
    );
    if (musicIndex >= 0) {
      musicList.value[musicIndex].isCollect = !musicCollect.value;
      store.commit("musicListCollect", {
        index: musicIndex,
        collect: !musicCollect.value,
      });
    }
    isShowMenu.value = false;
    sessionStorage.setItem("musicList", JSON.stringify(musicList.value));
  }
};

const deleteMusic = () => {
  if (musicId.value) {
    const musicIndex = musicList.value.findIndex(
      (item) => item.id === Number(musicId.value)
    );
    if (musicIndex >= 0) {
      musicList.value.splice(musicIndex, 1);
      store.commit("deleteMusiclist", musicList.value[musicIndex].id);
    }
    sessionStorage.setItem("musicList", JSON.stringify(musicList.value));
    isShowMenu.value = false;
  }
};

const handleHover = (state: PointerState) => {
  if (!isMaxFontSize.value) {
    state.target.style.fontSize = "26px";
  } else {
    state.target.style.fontSize = "16px";
  }
  isMaxFontSize.value = !isMaxFontSize.value;
};

onMounted(() => {
  const MusicList = sessionStorage.getItem("musicList");
  if (MusicList) {
    musicList.value = JSON.parse(MusicList);
    store.commit("addMusiclist", musicList.value);
  } else {
    musicList.value = store.state.musicList;
  }
  document.addEventListener("click", function () {
    isShowMenu.value = false;
  });
});
</script>

<style lang="less" scoped>
@import "./index.less";
</style>